package Threads.ThreadPool.DIY_ThreadPool;

import java.util.HashSet;
import java.util.concurrent.TimeUnit;

public class ThreadPool {
    //task queue
    private BlockingQueue<Runnable> taskQueue;

    //set of the woker(threads)
    private HashSet<Worker> workers=new HashSet<Worker>();

    //size of core threads
    private int coreSize;

    //timeout
    private long timeout;

    private TimeUnit timeUnit;

    private RejectPolicy<Runnable> rejectPolicy;

    public ThreadPool(int coreSize, long timeout, TimeUnit timeUnit,int queuesize, RejectPolicy<Runnable> rejectPolicy) {
        this.coreSize = coreSize;
        this.timeout = timeout;
        this.timeUnit = timeUnit;
        this.rejectPolicy = rejectPolicy;
        this.taskQueue=new BlockingQueue<>(queuesize);
        this.rejectPolicy=rejectPolicy;
    }

    //execute the task
    public void execute(Runnable task){
        synchronized (workers){
            if (workers.size()<coreSize){
                Worker worker = new Worker(task);
                System.out.println("worker "+worker+" is added");
                workers.add(worker);
                worker.start();
            }else {
                taskQueue.tryPut(rejectPolicy,task);
            }
        }
    }

    private class Worker extends Thread{
        private Runnable task;

        public Worker(Runnable task){
            this.task=task;
        }

        @Override
        public void run() {
            //当前任务不是空，执行当前任务
            //当前task执行完毕，接着从任务队列中取任务并执行
            while (task!=null||(task=taskQueue.poll(timeout,timeUnit))!=null){
                try{
                    System.out.println(task+"is running------");
                    task.run();
                }finally {
                    task=null;
                }
            }
            //如果任务队列中也没有任务，来到这里，把这个worker清除（没有任务做了，所以要清除，避免资源浪费）
            synchronized (workers){
                System.out.println(this+"will be removed");
                workers.remove(this);
            }
        }
    }
}
